package utils

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"time"
)

type Message struct {
	MsgType   int `json:"msg_type"	` // 1 pingpong 2 jobStruct 3jobResultStruct 4clientupdatename 5 str
	Msg       json.RawMessage
	Timestamp int64 `json:"timestamp"`
}

func (m *Message) DD() {}

type MessageInterface interface {
	DD()
}

func ToJson(messageInterface MessageInterface) []byte {
	data, err := json.Marshal(messageInterface)
	if err != nil {
		log.Println("convert to json err :", err.Error())
		return nil
	}
	return data
}

func (m *Message) Code(key string) ([]byte, error) {
	data := m.ToJson()
	if data != nil {
		return DesEncrypt(data, []byte(key))
	}
	return nil, errors.New("编码失败")
}

func (m *Message) DeCode(key string) ([]byte, error) {
	return nil, nil
}

// 1
type PingPong struct {
	Key string
}

// 2 任务
type JobMessage struct {
	JobId   uint      `json:"job_id"`
	Jobs    []Command `json:"jobs"`
	Timeout int       `json:"timeout"`
}

// 4 client发起改名请求的消息格式
type ClientInfoMessage struct {
	HostName       string  `json:"host_name"`
	AgentVersion   float64 `json:"agent_version"`
	HardwareAddr   string  `json:"hardware_addr"`
	System         string  `json:"system"`
	SystemVersion  string  `json:"system_version"`
	SystemPlatform string  `json:"system_platform"`
	Kernel         string  `json:"kernel"`
	ServerType     int     `json:"server_type"`
}

//5 字符串数据
type StrMessage struct {
	Str string `json:"str"`
}

// 6 agent 发送的文件列表
type FileListMessage struct {
	Hostname string
	FileList []FileInfo
}
type FileInfo struct {
	Name    string
	ModTime time.Time
	Size    int64
}

// 7 agent 收到上传文件后的消息回复
type UploadFileInfoMessage struct {
	Name    string
	ModTime time.Time
	Size    int64
	Md5     string
}

// 8 serever向agent

//func (g *GetAgentConf)ToJson()[]byte{
//	data,err :=json.Marshal(g)
//	if err != nil {
//		log.Println("convert to json err :",err.Error())
//		return nil
//	}
//	return data
//}

func (j *FileListMessage) DD() {}

func (j *UploadFileInfoMessage) DD() {}

func (j *StrMessage) DD() {}

// 发消息的格式
func (j *ClientInfoMessage) DD() {}

// 给用户发消息的格式
func (j *JobMessage) ToJson() []byte {
	// fmt.Printf("%v,%T\n",r,r)
	data, err := json.Marshal(j)
	if err != nil {
		log.Println("convert to json err :", err.Error())
		return nil
	}
	log.Println("发送的消息为：", string(data))
	return data
}

type JobResult struct {
	JobId     uint
	JobLog    string
	JobStatus string
}

func (j *JobResult) DD() {}

// 把新请求转换为对象
func NewRequest(buf, key []byte) *Message {
	b, err := DesDecrypt(buf, key)
	if err != nil {
		log.Println("解码失败", err.Error())
		return nil
	}
	log.Println("收到消息数据：" + string(b))
	m := Message{}
	err = json.Unmarshal(b, &m)
	if err != nil {
		log.Println("解析出错：", err.Error())
		return nil
	}
	//log.Println("解析前：",string(b))

	return &m
}

// 给用户发消息的格式
func (m *Message) ToJson() []byte {
	// fmt.Printf("%v,%T\n",r,r)
	data, err := json.Marshal(m)
	if err != nil {
		log.Println("convert Message to json err :", err.Error())
		return nil
	}
	fmt.Println(string(data))
	return data
}

// 创建消息
func NewMessage(key string, msgType int, msg []byte) []byte {
	m := &Message{
		MsgType:   msgType,
		Timestamp: time.Now().Unix(),
		Msg:       msg,
	}

	b, err := DesEncrypt(m.ToJson(), []byte(key))
	if err != nil {
		fmt.Println("创建消息时加密错误")
		return nil
	}
	return b
}

// 创建消息2
func NewMessage2(key string, msgType int, messageinterface MessageInterface) []byte {
	msg := ToJson(messageinterface)
	m := &Message{
		MsgType:   msgType,
		Timestamp: time.Now().Unix(),
		Msg:       msg,
	}

	b, err := DesEncrypt(ToJson(m), []byte(key))
	if err != nil {
		fmt.Println("创建消息时加密错误")
		return nil
	}
	return b
}

func (m *Message) ToByte(key string) []byte {
	b, err := DesEncrypt(m.ToJson(), []byte(key))
	if err != nil {
		fmt.Println("创建消息时加密错误")
		return nil
	}
	return b
}
